package com.yuneec.fly.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class DES {
    private static final String key = "ksYuN2eC";

    // --------------------对单个文件进行加解密---------------------------//

    /**
     * 解密文件
     *
     * @param srcFile  解密的文件
     * @param distFile 解密后的文件
     * @throws Exception
     */
    public static void decrypt(String srcFile, String distFile)
            throws Exception {
        InputStream is = null;
        OutputStream out = null;
        CipherOutputStream cos = null;
        try {
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
            byte[] buffer = new byte[1024];
            is = new FileInputStream(srcFile);
            File f = new File(distFile);
            if (!f.exists()) {
                f.createNewFile();
            }
            out = new FileOutputStream(distFile);
            cos = new CipherOutputStream(out, cipher);
            int r;
            while ((r = is.read(buffer)) >= 0) {
                cos.write(buffer, 0, r);
            }
        } catch (Exception e) {
            throw e;
        } finally {
            cos.close();
            is.close();
            out.close();
        }
    }

    /**
     * 加密文件
     *
     * @param srcFile  加密的文件
     * @param distFile 加密后的文件
     * @throws Exception
     */
    public static void encrypt(String srcFile, String distFile)
            throws Exception {
        InputStream is = null;
        OutputStream out = null;
        CipherInputStream cis = null;
        try {
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
            is = new FileInputStream(srcFile);
            File f = new File(distFile);
            if (!f.exists()) {
                f.createNewFile();
            }
            out = new FileOutputStream(distFile);
            cis = new CipherInputStream(is, cipher);
            byte[] buffer = new byte[1024];
            int r;
            while ((r = cis.read(buffer)) > 0) {
                out.write(buffer, 0, r);
            }
        } catch (Exception e) {
            throw e;
        } finally {
            cis.close();
            is.close();
            out.close();
        }
    }

    // ------------------------------------加解密字符串-----------------------------------//
    // 解密数据
    public static String decrypt(String message) throws Exception {

        byte[] bytesrc = convertHexString(message);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        byte[] retByte = cipher.doFinal(bytesrc);
        return new String(retByte);
    }

    // 加密数据
    public static byte[] encrypt(String message) throws Exception {
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        return cipher.doFinal(message.getBytes("UTF-8"));
    }

    public static byte[] convertHexString(String ss) {
        byte digest[] = new byte[ss.length() / 2];
        for (int i = 0; i < digest.length; i++) {
            String byteString = ss.substring(2 * i, 2 * i + 2);
            int byteValue = Integer.parseInt(byteString, 16);
            digest[i] = (byte) byteValue;
        }
        return digest;
    }

    public static String toHexString(byte b[]) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String plainText = Integer.toHexString(0xff & b[i]);
            if (plainText.length() < 2)
                plainText = "0" + plainText;
            hexString.append(plainText);
        }
        return hexString.toString();
    }

    public static void main(String[] args) throws Exception {
        String value = "test1234 ";
        String jiami = java.net.URLEncoder.encode(value, "utf-8").toLowerCase();

        System.out.println("加密数据:" + jiami);
        String a = toHexString(encrypt(jiami)).toUpperCase();
        System.out.println("加密后的数据为:" + a);

        String b = java.net.URLDecoder.decode(decrypt(a), "utf-8");
        System.out.println("解密后的数据:" + b);

    }

    /**
     * 文件重命名
     *
     * @param oldname 原来的文件名
     * @param newname 新文件名
     */
    public static void renameFile(String oldname, String newname) {
        if (!oldname.equals(newname)) {// 新的文件名和以前文件名不同时,才有必要进行重命名
            File oldfile = new File(oldname);
            File newfile = new File(newname);
            if (!oldfile.exists()) {
                return;// 重命名文件不存在
            }
            if (newfile.exists())// 若在该目录下已经有一个文件和新文件名相同，则不允许重命名
                System.out.println(newname + "已经存在！");
            else {
                oldfile.renameTo(newfile);
            }
        } else {
            System.out.println("新文件名和旧文件名相同...");
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName 被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        boolean flag = false;
        File file = new File(fileName);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 加密后的文件临时文件名
     *
     * @param fileName 加密的文件名
     * @return
     */
    public static String tempFileName(String fileName) {
        String tempFileName = "";
        int length = fileName.length();
        tempFileName = fileName.substring(0, length - 4) + "_temp"
                + fileName.substring(length - 4 + 1, length);
        return tempFileName;
    }

    public static String creatEncryptPath(String fileName) {
        String[] paths = fileName.split("/");
        String flightPath = paths[1]; //FlightLog
        String encryptName = paths[3]; // .csv
        String FlightEncryptLog = "FlightEncryptLog";
        String FileEncryptPath = fileName.replace("FlightLog", "FlightEncryptLog");  //加密文件全路径

        String telFileEncryptPath = "sdcard/FlightEncryptLog/Telemetry";
        String remFileEncryptPath = "sdcard/FlightEncryptLog/Remote";
        String remGPSFileEncryptPath = "sdcard/FlightEncryptLog/RemoteGPS";
        File file1 = new File(telFileEncryptPath);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        File file2 = new File(remFileEncryptPath);
        if (!file2.exists()) {
            file2.mkdirs();
        }
        File file3 = new File(remGPSFileEncryptPath);
        if (!file3.exists()) {
            file3.mkdirs();
        }
        return FileEncryptPath;
    }

    public static void logEncrypt(String fileName) {
        if (fileName != null) {
            File file = new File(fileName);
            if (file.exists()) {
                String tempName = tempFileName(fileName);
                try {
                    String FileEncryptPath = creatEncryptPath(fileName);
                    encrypt(fileName, FileEncryptPath);
//					deleteFile(fileName);
//					renameFile(tempName, fileName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
